package com.jtpay.payresulthelper.ui.activity;

import android.app.AlertDialog;
import android.app.NotificationManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Build;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.text.method.ScrollingMovementMethod;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import com.google.gson.JsonObject;
import com.jtpay.payresulthelper.R;
import com.jtpay.payresulthelper.app.HelperApplication;
import com.jtpay.payresulthelper.http.dataStructure.BasicResponse;
import com.jtpay.payresulthelper.http.listener.TransApiResultListener;
import com.jtpay.payresulthelper.model.AliDbModel;
import com.jtpay.payresulthelper.provider.AliDbDataProvider;
import com.jtpay.payresulthelper.util.ActivityHelper;
import com.jtpay.payresulthelper.util.AlarmSoundManager;
import com.jtpay.payresulthelper.util.LogUtil;
import com.jtpay.payresulthelper.util.PayContext;
import com.jtpay.payresulthelper.util.manager.ToastUtil;

import java.util.List;

import static com.jtpay.payresulthelper.constant.HooKConstant.ACTION_AUTO_QUERY_ORDER;
import static com.jtpay.payresulthelper.constant.HooKConstant.ACTION_MAKE_QR_CODE;
import static com.jtpay.payresulthelper.provider.AliDbDataProvider.*;
import static com.jtpay.payresulthelper.util.ActivityHelper.startAliApp;
import static com.jtpay.payresulthelper.util.ActivityHelper.stopAliApp;
import static com.jtpay.payresulthelper.util.ApiConstant.*;
import static com.jtpay.payresulthelper.util.PayContext.*;

public class MainActivity extends BaseActivity {

    private EditText etMerchantCode;
    private TextView mLogContent;
    private Button btnRegister;
    private Button btnOfflineAlarm;
    private int logCount = 0;//log lines count
    private Menu menu;
    private List<AliDbModel> mList;

    @Override
    protected void onResume() {
        super.onResume();
        openAccessibilityServiceSettingIfNeed(false);
    }

    @Override
    protected void onDestroy() {
        LogUtil.log("ali_payResult MainActivity onDestroy");
        unRegisterReceiver();
        stopAliApp();
        super.onDestroy();
    }

    @Override
    protected int setLayoutId() {
        return R.layout.activity_main;
    }

    @Override
    protected void initView() {
        etMerchantCode = findViewById(R.id.et_product_account_code);
        mLogContent = findViewById(R.id.LogContent);
        btnRegister = findViewById(R.id.btn_register);
        btnOfflineAlarm = findViewById(R.id.btn_offline_alarm);
        mLogContent.setMovementMethod(ScrollingMovementMethod.getInstance());
        registerReceiver();
        etMerchantCode.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                MenuItem toolItem = menu.findItem(R.id.menu_tool);
                toolItem.setVisible(!toolItem.isVisible());
                return true;
            }
        });
        String shopCode = getAliAccount(this);
        if (TextUtils.isEmpty(shopCode)) {
            setViewVisibility(btnRegister, View.VISIBLE);
        } else {
            etMerchantCode.setText(shopCode);
        }
    }

    @Override
    protected void initData() {
        PayContext.isFirst = true;
        doRequestPermissions();
        resetAliAccount();
        startNotifyListener();
        AlarmSoundManager.getInstance().setChangedListener(new AlarmSoundManager.AlarmStatusChangedListener() {
            @Override
            public void alarmStatus(boolean isPlaying) {
                if (isPlaying) {
                    setViewVisibility(btnOfflineAlarm, View.VISIBLE);
                } else {
                    setViewVisibility(btnOfflineAlarm, View.GONE);
                }
            }
        });
        DB_DELETE_TABLE_DAYS = sharedPreferenceUtil.SP_READ_INTEGER(this,
                SP_KEY_DB_DELETE_DAYS, DB_DELETE_TABLE_DAYS_DEF);
        DEFAULT_TIMEOUT = sharedPreferenceUtil.SP_READ_INTEGER(this,
                SP_KEY_PULSE_SPEED, DEFAULT_TIMEOUT_DEF);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        this.menu = menu;
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        switch (id) {
            case R.id.menu_log_clean:
                mLogContent.setText(getString(R.string.log_content_def));
                break;
            case R.id.menu_start_service:
                openAccessibilityServiceSettingIfNeed(true);
                break;
            case R.id.menu_set_account_info:
                setFocusable(etMerchantCode, true);
                VerifyAccountResult = false;
                setViewVisibility(btnRegister, View.VISIBLE);
                stopPulseSpeed();
                break;
            case R.id.exit:
                android.os.Process.killProcess(android.os.Process.myPid());
                break;
            case R.id.openAccessService:
                openAccessibilityServiceSetting();
                break;
            case R.id.openProgramSetting:
                openProgramSetting();
                break;
            case R.id.menu_pay_result_upload:
                uploadPayResult();
                break;
            case R.id.menu_notify_setting_ui:
                openNotifySettingUI();
                break;
            case R.id.menu_upload_error_data:
                uploadErrorPayResult(false);
                break;
            case R.id.menu_delete_db:
                deleteAliDb(this);
                break;
            case R.id.menu_pulse_speed:
                pulseSpeed();
                break;
            case R.id.menu_start_alarm:
                AlarmSoundManager.getInstance().play();
                break;
            case R.id.menu_alarm_set:
                startAlarmSettingUI();
                break;

        }
        return super.onOptionsItemSelected(item);
    }

    private Runnable verifyAccountRunnable = new Runnable() {
        @Override
        public void run() {
            String shopCode = etMerchantCode.getText().toString();
            if (TextUtils.isEmpty(shopCode)) {
                showLog(getString(R.string.merchant_code_null_tips));
                return;
            }
            PayContext.VerifyAccountStatus = 1;
            ActivityHelper.startPersonCenterActivity();
        }
    };

    public void programStart(View view) {
        /*stopAliApp();
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                startAliApp();
            }
        }, 500);*/

        NotificationManager notificationManager =
                (NotificationManager) HelperApplication.getContext().getSystemService(Context.NOTIFICATION_SERVICE);
        if (notificationManager == null) {
            showLog("NotificationManager null!");
            return;
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
                && !notificationManager.isNotificationPolicyAccessGranted()) {
            showLog(getString(R.string.notification_policy_access_tips));
            Intent intent = new Intent(Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);
            HelperApplication.getContext().startActivity(intent);
            return;
        }
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(R.string.alert)
                .setMessage(R.string.product_alert_message)
                .setPositiveButton(R.string.submit, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        showLog(getString(R.string.in_production));
                        PayContext.resetErrorCount();
                        startAliApp();
                        mHandler.postDelayed(verifyAccountRunnable, 1500);
                    }
                })
                .create()
                .show();
    }

    /**
     * @param view target view stopAlarm
     */
    public void stopAlarm(View view) {
        AlarmSoundManager.getInstance().stop();
    }

    public void makeOrder(View view) {
        LogUtil.log("makeOrder");
        sendBroadcast(new Intent(ACTION_MAKE_QR_CODE));
    }

    public void serverRegister(View view) {
        String shopCode = etMerchantCode.getText().toString();
        if (TextUtils.isEmpty(shopCode)) {
            showLog(getString(R.string.merchant_code_null_tips));
            return;
        }
        getApiHelper().getRegisterAPI(shopCode, new TransApiResultListener<BasicResponse<JsonObject>>() {
            @Override
            public void trans(BasicResponse<JsonObject> data) {
                showToast(data.getMsg());
                if (HTTP_SUCCESS.equals(data.getMsg())) {
                    setViewVisibility(btnRegister, View.GONE);
                }
            }
        });
    }

    @Override
    public void uploadPayResult() {
        AliDbModel model;
        if (ORDER_TASK_STATUS != 2) {
            model = AliDbDataProvider.selectAliDbInfo(this);
        } else {
            model = AliDbDataProvider.selectAliSupplementInfo(this);
        }
        uploadPayResult(model, -1);
    }

    private void uploadPayResult(final AliDbModel model, final int index) {
        if (model == null) {
            LogUtil.log("uploadPayResult AliDbModel null");
            return;
        }
        getApiHelper().noticeAPI(0, model, new TransApiResultListener<String>() {
            @Override
            public void trans(String data) {
                showLog("payResult " + data);
                if (ORDER_TASK_STATUS != 2) {
                    AliDbDataProvider.update(model.get_id(), "2", MainActivity.this);
                } else {
                    AliDbDataProvider.updateSupplement(model.get_id(), "2", MainActivity.this);
                }
                if (index >= 0) {
                    doUploadList(index + 1);
                }
            }
        });
    }

    @Override
    protected void stopPulseSpeed() {
        getApiHelper().removeAuthorizeCallback();
        getApiHelper().cleanBasicResponse();
        stopAliApp();
    }

    @Override
    protected void pulseSpeed() {
        if (!VerifyAccountResult) {
            showLog(getString(R.string.account_no_verify_tips));
            return;
        }
        resetErrorCount();
        getApiHelper().authorizeAPI(new TransApiResultListener<String>() {
            @Override
            public void trans(String data) {
                getApiHelper().getServerTaskAPI(0);
            }
        });
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        checkRequestPermissions();
    }

    /**
     * @param content String
     */
    @Override
    protected void showLog(final String content) {
        LogUtil.log(content);
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                logCount++;
                if (logCount == LOG_CLEAN_LINE) {
                    mLogContent.setText(String.format("%s\n", getString(R.string.log_content_def)));
                    logCount = 0;
                }
                mLogContent.append(content + "\n");
                int offset = mLogContent.getLineCount() * mLogContent.getLineHeight();
                if (offset > mLogContent.getHeight()) {
                    mLogContent.scrollTo(0, offset - mLogContent.getHeight());
                }
            }
        });
    }

    /**
     * @param content String
     */
    @Override
    protected void showToast(String content) {
        showLog(content);
        ToastUtil.showShort(content);
    }

    @Override
    protected void verifyResult(final boolean result) {
        getApiHelper().accountCheckAPI(result, new TransApiResultListener<String>() {
            @Override
            public void trans(String data) {
                showLog("verifyResult : " + data);
                if (result) {
                    setFocusable(etMerchantCode, false);
                    setViewVisibility(btnRegister, View.GONE);
                    uploadErrorPayResult(true);
                }
            }
        });
    }

    /**
     * @param needSendBroadcast boolean
     */
    private void uploadErrorPayResult(boolean needSendBroadcast) {
        mList = selectAliDbErrorListInfo(this);
        if ((mList == null || mList.size() < 1) && needSendBroadcast) {
            LogUtil.log(getString(R.string.notice_error_null_info));
            deleteAliDbTargetData(this, DB_DELETE_TABLE_DAYS);
            sendBroadcast(new Intent(ACTION_AUTO_QUERY_ORDER));
            return;
        } else if ((mList == null || mList.size() < 1)) {
            showLog(getString(R.string.notice_error_null_info));
            return;
        }
        LogUtil.log(getString(R.string.notice_error_info) + mList.size());
        doUploadList(0);
    }

    private void doUploadList(int index) {
        if (mList == null || mList.size() < 1) {
            return;
        }
        if (mList.size() > index) {
            uploadPayResult(mList.get(index), index);
        } else {
            uploadErrorPayResult(true);
        }
    }

}
